package org.geektimes.projects.user.oauth2;

import org.apache.commons.lang3.StringUtils;
import org.geektimes.base.util.ReflectionUtils;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import java.lang.reflect.Field;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* 基于servlet context 加载的配置的 oauht2处理器  
* @author : lsq
*/
public class ServletContextOAuth2Handler extends OAuth2Handler{

	private static final String PREFIX = "oauth2.";

	private static final String PARAM_CONFIGURATION_NAME = "paramConfiguration";

	/**
	 * 初始化servlet context 中的配置
	 * @param config servlet config
	 */
	@Override
	protected void onInit(ServletConfig config) {
		ServletContext servletContext = config.getServletContext();
		Map<String ,OAuth2Configuration> configurationMap = new HashMap<>();
		Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
		//获取属性字段对象
		List<Field> fields = ReflectionUtils.getFields(DefaultOAuth2Configuration.class, Object.class);
		Map<String, Field> propertyNameMap = fields.stream().collect(Collectors.toMap(Field::getName, Function.identity()));

		List<Field> fields1 = ReflectionUtils.getFields(DefaultOAuth2Configuration.ParamConfiguration.class, Object.class);
		Map<String, Field> propertyNameMap1 = fields1.stream().collect(Collectors.toMap(Field::getName, Function.identity()));
		//构建配置对象
		while (initParameterNames.hasMoreElements()){
			String name = initParameterNames.nextElement();
			if (name.startsWith(PREFIX)){
				String[] split = name.split("\\.");
				String originName = split[1];
				//初始化配置对象
				OAuth2Configuration oAuth2Configuration = configurationMap.get(originName);
				if (oAuth2Configuration == null){
					oAuth2Configuration = new DefaultOAuth2Configuration();
					configurationMap.put(originName , oAuth2Configuration);
				}
				//如果是OAuth2Configuration中的属性
				if (split.length == 3){
					String propertyName = split[2];
					Field field = propertyNameMap.get(propertyName);
					field.setAccessible(true);
					ReflectionUtils.set(field , oAuth2Configuration , servletContext.getInitParameter(name));
				}
				//如果是OAuth2Configuration#ParamConfiguration中的属性
				else if (split.length == 4 && PARAM_CONFIGURATION_NAME.equals(split[2])) {
					String propertyName = split[3];
					Field field = propertyNameMap1.get(propertyName);
					field.setAccessible(true);
					ReflectionUtils.set(field , oAuth2Configuration ,servletContext.getInitParameter(name) );
				}
			}
		}
		setConfigs(configurationMap.entrySet().stream().map(item -> {
			DefaultOAuth2Configuration value = (DefaultOAuth2Configuration) item.getValue();
			value.setOriginName(item.getKey());
			return value;
		}).collect(Collectors.toList()));
		addOAuth2Authentication(new MaYunOAuth2Authentication());
	}
}
